<?php
/**
 * 支付异步回调地址
 * Created by PhpStorm.
 * User: Jmashimaro
 * Date: 2015/5/15
 * Time: 13:24
 */
require ROOT_PATH.'/includes/libraries/sms.lib.php';
class NotifyApp extends MallbaseApp {

    /**
     * 公共类的实例
     * @var CommonApp
     * @author jyx
     * @date 2015/08/04
     */
    private $common;
    /**
     * 构造函数
     */
    public function __construct() {
        $this->common = new CommonApp();
    }


    /***
     * 支付宝回调地址
     * 服务端异步回调接口
     * @author jyx
     * @date 2015/09/15
     */
    public function alipaynotify(){
        $action = '支付宝回调地址';
        setLogParameter($action);
        $alipay_config = array();
        $filename = ROOT_PATH.'/includes/payments/api_alipay/log.txt';
        $date = date('Y-m-d H:i:s', time());
        @file_put_contents($filename, $date."\r\n", FILE_APPEND);
        require_once(ROOT_PATH . "/includes/payments/api_alipay/alipay.config.php");
        require_once(ROOT_PATH . "/includes/payments/api_alipay/lib/alipay_notify.class.php");

        $uri = $_SERVER['REQUEST_URI'];//请求的uri地址
        $content = serialize($_POST);
        //计算得出通知验证结果
        $alipayNotify = new AlipayNotify($alipay_config);
        $verify_result = $alipayNotify->verifyNotify();
        if($verify_result) {//验证成功
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代
            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表

            //商户订单号
            $out_trade_no = $this->get_gp('out_trade_no', 'P');

            //支付宝交易号

            $trade_no = $this->get_gp('trade_no', 'P');

            //交易状态
            $trade_status = $this->get_gp('trade_status', 'P');

            if($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') {

                $model_order = m('order');
                /* 开启事物 */
                $model_order->begin();

                $sql = "SELECT order_id,order_sn,`status` FROM `".DB_PREFIX."order` WHERE order_sn='{$out_trade_no}' OR pay_sn='{$out_trade_no}'";
                $order_info = $model_order->getAll($sql);
                if (!$order_info) {
                    /* 没有该订单 */
                    echo "fail";
                    //添加错误日志信息
                    $this->common->addLogs($uri, $content, '该订单信息不存在！' ,'0');
                    exit;
                }
                foreach($order_info as $key=>$value) {
                    if ($value['status'] == ORDER_PENDING) {
                        $info = array(
                            'status'        =>  ORDER_ACCEPTED,
                            'out_trade_sn'  =>  $trade_no,
                            'pay_time'      =>  time(),
                        );

                        $flag = $model_order->edit($value['order_id'], $info);
                        if ($flag === false) {
                            $model_order->rollback();
                            echo "fail";
                            //添加错误日志信息
                            $this->common->addLogs($uri, $content, '更新订单信息失败！' ,'0');
                            exit;
                        }
                        //查询出订单商品信息
                        $sql = "SELECT spec_id,quantity,goods_id FROM ".DB_PREFIX."order_goods WHERE order_id={$value['order_id']}";
                        $rows = $model_order->getAll($sql);
                        foreach ($rows as $val) {
                            //更新销量
                            $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_statistics WHERE goods_id={$val['goods_id']}";
                            if ($model_order->getRow($sql)) {
                                $sql = "UPDATE ".DB_PREFIX."goods_statistics SET sales=sales+{$val['quantity']} WHERE goods_id={$val['goods_id']}";
                                $rs = $model_order->query($sql);
                            } else {
                                $sql = "INSERT INTO ".DB_PREFIX."goods_statistics (goods_id,sales) VALUES ({$val['goods_id']}, {$val['quantity']})";
                                $rs = $model_order->query($sql);
                            }
                            //更新库存信息失败
                            if ($rs === false) {
                                $model_order->rollback();
                                echo "fail";
                                //添加错误日志信息
                                $this->common->addLogs($uri, $content, '更新销量信息失败！' ,'0');
                                exit;
                            }
                            //更新库存信息
                            $sql = "UPDATE ".DB_PREFIX."goods_spec SET stock = stock-".intval($val['quantity'])." WHERE spec_id = ".$val['spec_id'];
                            $update = $model_order->query($sql);
                            if ($update === false) {
                                /* 回滚事务 */
                                $model_order->rollback();
                                echo "fail";
                                //添加错误日志信息
                                $this->common->addLogs($uri, $content, '更新库存信息失败！' ,0);
                                exit;
                            }
                            //商品库存等于0，则清除购物车中的信息
                            $flagss = $this->common->dropCart($model_order, $val['spec_id']);
                            if ($flagss === false) {
                                $model_order->rollback();
                                echo "fail";
                                //添加错误日志信息
                                $this->common->addLogs($uri, $content, '清除购物车中的商品失败！' , 0);
                                exit;
                            }
                            //商品库存等于0，则商品下架
                            $flags = $this->common->soldOut($val['goods_id']);
                            if ($flags === false) {
                                $model_order->rollback();
                                echo "fail";
                                //添加错误日志信息
                                $this->common->addLogs($uri, $content, '更新活动库存信息失败！' ,0);
                                exit;
                            }
                        }
                    }
                }

                /* 提交事务 */
                $model_order->commit();
            }

            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

            echo "success";		//请不要修改或删除

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        } else {
            //验证失败
            echo "fail";
            //添加错误日志信息
            $this->common->addLogs($uri, $content, '支付验证失败！' ,'0');

            //调试用，写文本函数记录程序运行情况是否正常
            //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
        }

    }

    /**
     * 微信异步回调
     * @author jyx
     * @date 2015/09/15
     */
    public function wxappnotify() {
        $action = '微信异步回调';
        setLogParameter($action);
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/log_.php");
        include_once(ROOT_PATH."/includes/payments/WxPayPubHelper/WxPayPubHelper.php");
        //以log文件形式记录回调信息
        $log_ = new Log_();
        $log_name = ROOT_PATH."/includes/payments/WxPayPubHelper/notify_url.log";//log文件路径

        //使用通用通知接口
        $notify = new Notify_pub();

        //存储微信的回调
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        $notify->saveData($xml);

        //验证签名，并回应微信。
        //对后台通知交互时，如果微信收到商户的应答不是成功或超时，微信认为通知失败，
        //微信会通过一定的策略（如30分钟共8次）定期重新发起通知，
        //尽可能提高通知的成功率，但微信不保证通知最终能成功。
        if($notify->checkSign() == FALSE){
            $notify->setReturnParameter("return_code","FAIL");//返回状态码
            $notify->setReturnParameter("return_msg","签名失败");//返回信息
        }else{
            $notify->setReturnParameter("return_code","SUCCESS");//设置返回码
        }
        $returnXml = $notify->returnXml();
        echo $returnXml;

        //==商户根据实际情况设置相应的处理流程，此处仅作举例=======

        //以log文件形式记录回调信息
        $log_->log_result($log_name,"【接收到的notify通知】:\n".$xml."\n");

        $code = 1;
        $uri = $_SERVER['REQUEST_URI'];
        $content = serialize(json_decode(json_encode($notify->data), true));

        if($notify->checkSign() == TRUE) {
            if ($notify->data["return_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
                $log_->log_result($log_name,"【通信出错】:\n".$xml."\n");
                //添加错误日志信息
                $this->common->addLogs($uri, $content, '【通信出错】！' ,$code);
            } elseif ($notify->data["result_code"] == "FAIL") {
                //此处应该更新一下订单状态，商户自行增删操作
                $log_->log_result($log_name,"【业务出错】:\n".$xml."\n");
                //添加错误日志信息
                $this->common->addLogs($uri, $content, '【业务出错】！' , $code);
            } else {
                //此处应该更新一下订单状态，商户自行增删操作
                $model_order = m('order');
                $model_order->begin();
                $sql = "SELECT order_id,order_sn,`status` FROM `".DB_PREFIX."order` WHERE order_sn='{$notify->data['out_trade_no']}' OR pay_sn='{$notify->data['out_trade_no']}'";
                $row = $model_order->getAll($sql);
                if ($row) {
                    foreach ($row as $key=>$value) {
                        if ($value['status'] == ORDER_PENDING) {
                            $sql = "UPDATE `".DB_PREFIX."order` SET `status`=".ORDER_ACCEPTED.",out_trade_sn='{$notify->data['transaction_id']}',
                                pay_time=".time()." WHERE order_sn='{$value['order_sn']}'";
                            $flag = $model_order->query($sql);
                            if ($flag === false) {
                                $log_->log_result($log_name,"【更新订单失败】:\n".$xml."\n");
                                $model_order->rollback();
                                //添加错误日志信息
                                $this->common->addLogs($uri, $content, '更新订单失败！' , $code);
                                echo 'fail';
                                exit;
                            }
                            //查询出订单商品信息
                            $sql = "SELECT spec_id,quantity,goods_id FROM ".DB_PREFIX."order_goods WHERE order_id={$value['order_id']}";
                            $rows = $model_order->getAll($sql);
                            foreach ($rows as $val) {
                                //更新销量
                                $sql = "SELECT goods_id FROM ".DB_PREFIX."goods_statistics WHERE goods_id={$val['goods_id']}";
                                if ($model_order->getRow($sql)) {
                                    $sql = "UPDATE ".DB_PREFIX."goods_statistics SET sales=sales+{$val['quantity']} WHERE goods_id={$val['goods_id']}";
                                    $rs = $model_order->query($sql);
                                } else {
                                    $sql = "INSERT INTO ".DB_PREFIX."goods_statistics (goods_id,sales) VALUES ({$val['goods_id']}, {$val['quantity']})";
                                    $rs = $model_order->query($sql);
                                }
                                //更新销量信息失败
                                if ($rs === false) {
                                    $model_order->rollback();
                                    echo "fail";
                                    //添加错误日志信息
                                    $this->common->addLogs($uri, $content, '更新销量信息失败！' , $code);
                                    exit;
                                }
                                //更新库存信息
                                $sql = "UPDATE ".DB_PREFIX."goods_spec SET stock = stock-".intval($val['quantity'])." WHERE spec_id = ".$val['spec_id'];
                                $update = $model_order->query($sql);
                                if ($update === false) {
                                    /* 回滚事务 */
                                    $model_order->rollback();
                                    /* 更新库存失败 */
                                    echo "fail";
                                    //添加错误日志信息
                                    $this->common->addLogs($uri, $content, '更新库存信息失败！' , $code);
                                    exit;
                                }

                                //商品库存等于0，则清除购物车中的信息
                                $flagss = $this->common->dropCart($model_order, $val['spec_id']);
                                if ($flagss === false) {
                                    $model_order->rollback();
                                    echo "fail";
                                    //添加错误日志信息
                                    $this->common->addLogs($uri, $content, '清除购物车中的商品失败！' , $code);
                                    exit;
                                }
                                //商品库存等于0，则商品下架
                                $flags = $this->common->soldOut($val['goods_id']);
                                if ($flags === false) {
                                    $model_order->rollback();
                                    echo "fail";
                                    //添加错误日志信息
                                    $this->common->addLogs($uri, $content, '商品下架失败！' , $code);
                                    exit;
                                }
                            }
                        }
                    }
                    $model_order->commit();
                }
                $log_->log_result($log_name,"【支付成功】:\n".$xml."\n");
            }

            //商户自行增加处理流程,
            //例如：更新订单状态
            //例如：数据库操作
            //例如：推送支付完成信息
        }

    }

}